package drds.plus.sql_process.optimizer.pre_processor;

import drds.plus.sql_process.abstract_syntax_tree.node.Node;
import drds.plus.sql_process.abstract_syntax_tree.node.query.Join;
import drds.plus.sql_process.abstract_syntax_tree.node.query.Query;

/**
 * 预先处理join
 *
 * <pre>
 * 1. 会遍历所有节点将right join的左右节点进行调换，转换成left join.
 *
 * 比如 A rightNode join B on A.id = B.id
 * 转化为 B leftNode join B on A.id = B.id
 *
 * </pre>
 */
public class JoinPreProcessor {

    public static Query optimize(Query query) {
        query = findAndChangeRightJoinToLeftJoin(query);
        return query;
    }

    /**
     * 会遍历所有节点将right join的左右节点进行调换，转换成left join.
     *
     * <pre>
     * 比如 A rightNode join B on A.id = B.id
     * 转化为 B leftNode join B on A.id = B.id
     * </pre>
     */
    private static Query findAndChangeRightJoinToLeftJoin(Query query) {
        for (Node node : query.getNodeList()) {
            findAndChangeRightJoinToLeftJoin((Query) node);
        }

        if (query instanceof Join && ((Join) query).isRightOuterJoin()) {
            /**
             * 如果带有其他非column=column条件，不能做这种转换，否则语义改变
             */
            if (query.getOtherJoinOnFilter() != null) {
                return query;
            }

            Join joinNode = (Join) query;
            joinNode.exchangeLeftAndRight();
            joinNode.build();
        }

        return query;
    }

}
